<template>
  <div class="app-container">
    <el-row>
      <el-card class="box-card">
        <div slot="header" class="clearfix">
          <span>测试用例导入</span>
        </div>
        <div style="margin-bottom:50px; width: 600px">
          <el-alert style="margin-bottom: 10px" title="目前只支持xls格式文件，请另存为97格式的文件" type="info" show-icon close-text="Get!" />
          <el-form ref="dataForm" :rules="rules" :model="temp" label-position="left" label-width="80px">
            <el-form-item label="文件" prop="url" style="margin-bottom: 30px;">
              <Upload v-model="temp" list_type="text" file_type=".xls" :multiple="false" />
              <el-link type="primary" :underline="false" style="margin-right: 15px" @click="getManualTemplate()">模版下载</el-link>
              <span />
            </el-form-item>
          </el-form>
          <div style="text-align: right">
            <el-button type="primary" :loading="importLoading" :disabled="typeof temp.serverFileName === 'undefined'" @click="importTestcase()">导入</el-button>
          </div>
        </div>
      </el-card>
    </el-row>

    <el-row style="margin-top: 50px;">
      <el-card class="box-card">
        <div slot="header" class="clearfix">
          <span>测试用例导出</span>
        </div>
        <div style="margin-bottom:50px; width: 800px">
          <el-alert close-text="Get!" show-icon style="margin-bottom: 10px" title="使用说明：" type="info">
            <div>1、点击 “同步数据” 获取当前项目下的所有目录数据；</div>
            <div>2、点击 “导出” 按钮开始导出数据；</div>
            <div>3、点击 “导出” 按钮后请不要切换页面也不要刷新页面，等待导出成功后按照提示下载导出文件。</div>
          </el-alert>
          <el-form ref="exportDataForm" label-position="left" label-width="0px">
            <el-form-item label="">
              <div style="text-align: right;">
                <el-button icon="el-icon-refresh" size="mini" type="primary" @click="loadCatalog">同步数据</el-button>
              </div>
              <div id="leftDiv" style="border: 1px solid #ebeef5; overflow-y: scroll; height: 400px;">
                <tree-component
                  ref="treeComponent"
                  :tree-data="fullDate"
                  show-checkbox
                />
              </div>
            </el-form-item>
            <el-form-item label="">
              导出文件类型
              <el-select v-model="exportFileType" placeholder="请选择导出文件类型" style="width: 150px">
                <el-option v-for="item in fileTypeOptions" :key="item.value" :disabled="item.disabled" :label="item.label" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-form>
          <div style="text-align: right">
            <el-button :disabled="fullDate.length === 0" :loading="exportLoading" type="primary" @click="exportTestcase()">导出</el-button>
          </div>
        </div>
      </el-card>
    </el-row>
  </div>
</template>

<script>
import Upload from '@/components/Upload'
import { deepClone } from '@/utils'
import { fileImport, getManualTemplate, fileExport } from '@/api/functional_test/test_case_manage/test_case'
import { listTreeCatalog } from '@/api/functional_test/catalog'
import { getTaskStatus } from '@/api/tools/taskManager'
import TreeComponent from '@/components/functional_test/Tree/index.vue'

export default {
  components: { Upload, TreeComponent },
  data() {
    return {
      fullDate: [],
      importLoading: false,
      exportLoading: false,
      temp: {
        id: undefined,
        url: '',
        serverFileName: undefined
      },
      exportFileType: 1,
      fileTypeOptions: [ // 文件类型 options
        {
          value: 1,
          label: 'excel'
        }, {
          value: 2,
          label: 'xmind',
          disabled: true
        }
      ],
      rules: {
        url: [
        ]
      }
    }
  },
  methods: {
    resetTemp() {
      this.temp = {
        id: undefined,
        url: '',
        serverFileName: undefined
      }
    },
    // 点击下载模版
    getManualTemplate() {
      getManualTemplate(this.temp.serverFileName).then(response => {
        // 获取文件名
        const contentDisposition = response.headers['content-disposition']
        let filename = 'unknown_file_name'
        if (contentDisposition && contentDisposition.includes('filename=')) {
          filename = contentDisposition.match(/filename=(.+)/)[1]
        }

        // 取得文件流，生成下载链接，下载文件
        const data = response.data
        const url = window.URL.createObjectURL(new Blob([data]))
        const downLink = document.createElement('a')
        downLink.href = url
        downLink.setAttribute('download', filename)
        document.body.appendChild(downLink)
        downLink.click()
        document.body.removeChild(downLink)
      })
    },
    // 点击开始导入测试用例
    importTestcase() {
      this.importLoading = true
      fileImport(this.temp.serverFileName, this.$store.getters.projectId).then(response => {
        this.temp.taskId = response.data.taskId
        this.$message({ message: '导入文件上传成功，开始异步数据导入!', type: 'success' })
        this.checkTaskStatus()
      })
    },
    // 查询导入结果
    checkTaskStatus() {
      this.checkTaskStatusTimer = setInterval(() => {
        getTaskStatus(this.temp.taskId).then(response => {
          if (response.data.status >= 3) {
            if (response.data.status === 5) {
              this.$message({ message: '数据导入成功!', type: 'success' })
            } else if (response.data.status === 3) {
              const h = this.$createElement
              this.$msgbox({
                title: '消息',
                message: h('p', null, [
                  h('span', null, response.data.msg + '：'),
                  h('a', { style: 'color: #409EFF', attrs: { href: response.data.detailData }}, '点击下载查看失败原因')
                ]),
                confirmButtonText: '确定'
              }).then(action => {
              })
            } else if (response.data.status === 4) {
              this.$message({ message: response.data.msg, type: 'error' })
            }
            clearInterval(this.checkTaskStatusTimer)
            this.resetTemp()
            this.importLoading = false
          }
        })
      }, 1000)
    },
    // 点击同步数据
    loadCatalog() {
      listTreeCatalog({
        projectId: this.$store.getters.projectId,
        type: 1,
        parentId: 0
      }).then(response => {
        this.fullDate = response.data
      })
    },
    // 递归，返回所有最早的全选节点
    recursionCheckedNode(allCheckedDataIncludeHalf, allCheckedData, node) {
      // 循环所有半选和全选的节点，判断节点是否勾选（可能是半选或全选）
      var maybeHalf = false
      for (var i = 0; i < allCheckedDataIncludeHalf.length; i++) {
        if (allCheckedDataIncludeHalf[i].key === node.key) {
          maybeHalf = true
          break
        }
      }

      if (maybeHalf) { // true 可能是半选或全选
        // 循环返回所有全选的节点，判断节点是否勾选（一定是全选）
        var checked = false
        for (var j = 0; j < allCheckedData.length; j++) {
          if (allCheckedData[j].key === node.key) {
            checked = true
            break
          }
        }

        if (checked) { // 全选则删除子字节点 并 返回
          delete node.children
          return node
        } else { // 半选则递归遍历子节点
          for (var k = 0; k < node.children.length; k++) {
            if (this.recursionCheckedNode(allCheckedDataIncludeHalf, allCheckedData, node.children[k]) === null) { // 递归返回 null，说明子节点没有勾选，删除当前节点
              node.children.splice(k, 1)
            }
          }
        }
      } else { // false 一定没有勾选
        return null
      }

      return node
    },
    // 点击导出测试用例
    exportTestcase() {
      const allCheckedDataIncludeHalf = this.$refs.treeComponent.getCheckedNodes(false, true) // 返回所有半选和全选的节点
      const allCheckedData = this.$refs.treeComponent.getCheckedNodes() // 返回所有全选的节点

      if (allCheckedData.length === 0) {
        this.$message({ message: '请先勾选需要导出的目录后，再点击 “导出” 按钮！', type: 'error' })
        return
      }

      // 循环所有半选和全选的节点，只保留跟节点
      const allRootData = []
      for (var i = 0; i < allCheckedDataIncludeHalf.length; i++) {
        if (allCheckedDataIncludeHalf[i].parentId === 0) {
          allRootData.push(deepClone(allCheckedDataIncludeHalf[i]))
        }
      }

      // 递归，返回所有最早的全选节点
      const arr = []
      for (var j = 0; j < allRootData.length; j++) {
        arr.push(this.recursionCheckedNode(allCheckedDataIncludeHalf, allCheckedData, allRootData[j]))
      }

      this.exportLoading = true
      fileExport({
        tree: arr,
        fileType: this.exportFileType
      }).then(response => {
        this.temp.taskId = response.data.taskId
        this.$message({ message: '开始异步导出数据，请稍后!', type: 'success' })
        this.checkExportTaskStatus()
      })
    },
    // 查询导出结果
    checkExportTaskStatus() {
      this.checkTaskStatusTimer = setInterval(() => {
        getTaskStatus(this.temp.taskId).then(response => {
          if (response.data.status >= 3) {
            if (response.data.status === 5) {
              const h = this.$createElement
              this.$msgbox({
                title: '消息',
                message: h('p', null, [
                  h('span', null, response.data.msg + '：'),
                  h('a', { style: 'color: #409EFF', attrs: { href: response.data.detailData }}, '点击下载导出数据')
                ]),
                confirmButtonText: '确定'
              }).then(action => {
              })
            } else if (response.data.status === 3 || response.data.status === 4) {
              this.$message({ message: response.data.msg, type: 'error' })
            }
            clearInterval(this.checkTaskStatusTimer)
            this.resetTemp()
            this.exportLoading = false
          }
        })
      }, 1000)
    }
  }
}
</script>
